package ee.ut.maxorato_macobo.oop.mudclient.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;

public class ClientWindow extends JFrame implements ComponentListener {
	private static final long serialVersionUID = -3254010441708549961L;
	
	private JTextPane inputPane;
	private JTextField outputPane;
	private JScrollPane scrollPane;
	private ControlsPanel controlsPanel;
	private String currentStyleName;
	private String styleFgColour;
	private boolean styleBoldEnabled;

	public ClientWindow(String frameName) {
		super(frameName);
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		setSize(600, 400);
		this.setMinimumSize(new Dimension(300, 150));
		setLayout(null);
		
		addComponentListener(this);
		
		controlsPanel = new ControlsPanel(120);
		add(controlsPanel);
		
		inputPane = new JTextPane();
		inputPane.setEditable(false);
		inputPane.setBorder(BorderFactory.createLineBorder(Color.black));
		inputPane.setBackground(Color.BLACK);
		
		scrollPane = new JScrollPane(inputPane);
		scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

		add(scrollPane);
		
		currentStyleName = "white-normal";
		
		styleFgColour = "white";
		styleBoldEnabled = false;
		
		generateStyle("white-normal", Color.LIGHT_GRAY);
		generateStyle("white-bright", Color.WHITE);
		generateStyle("black-normal", Color.BLACK);
		generateStyle("black-bright", Color.GRAY);
		generateStyle("red-normal", new Color(0x800000));
		generateStyle("red-bright", new Color(0xFF0000));
		generateStyle("green-normal", new Color(0x008000));
		generateStyle("green-bright", new Color(0x00FF00));
		generateStyle("yellow-normal", new Color(0x808000));
		generateStyle("yellow-bright", new Color(0xFFFF00));
		generateStyle("blue-normal", new Color(0x000080));
		generateStyle("blue-bright", new Color(0x0000FF));
		generateStyle("magenta-normal", new Color(0x800080));
		generateStyle("magenta-bright", new Color(0xFF00FF));
		generateStyle("cyan-normal", new Color(0x008080));
		generateStyle("cyan-bright", new Color(0x00FFFF));
		
		outputPane = new ClientCmdField();
		add(outputPane);
		
		setVisible(true);
		
		outputPane.requestFocusInWindow();
		
		processSize();
	}
	
	public void generateStyle(String styleName, Color foregroundColor) {
		Style style = inputPane.addStyle(styleName, null);
		StyleConstants.setForeground(style, foregroundColor);
		StyleConstants.setBackground(style, Color.BLACK);
		StyleConstants.setBold(style, true);
		StyleConstants.setFontSize(style, 12);
		StyleConstants.setFontFamily(style, "Consolas");
	}
	
	public void processSize() {
		Insets edges = getInsets();
		int fw = getWidth() - edges.left - edges.right;
		int fh = getHeight() - edges.top - edges.bottom;
		
		scrollPane.setBounds(0, 0, fw - controlsPanel.width, fh - 25);
		
		outputPane.setLocation(0, fh - 22);
		outputPane.setSize(fw, 22);
		
		controlsPanel.setBounds(fw - controlsPanel.width, 0, controlsPanel.width, fh - 25);
		
		scrollPane.revalidate();
		this.repaint();
	}
	
	public void scrollInputToEnd() {
		inputPane.setCaretPosition(inputPane.getDocument().getLength());
	}
	
	public void addInputToView(String inputText) {
		Document doc = inputPane.getDocument();
		
		int findPos = 0, endPos, prevFind = 0;
		
		while((findPos = inputText.indexOf("\033[", findPos)) >= 0) {
			if(prevFind < findPos) {
				try {
					doc.insertString(doc.getLength(), inputText.substring(prevFind, findPos), inputPane.getStyle(currentStyleName));
				} catch (BadLocationException e) { }
			}
			
			endPos = inputText.indexOf("m", findPos + 1);
			
			if(endPos >= 0) {
				String[] tokens = inputText.substring(findPos + 2, endPos).split(";");
				
				for(String token : tokens) {
					int tokenValue = 0;
					
					try {
						tokenValue = Integer.parseInt(token);
					} catch(Exception e) { }
					
					if(tokenValue == 0) {
						styleFgColour = "white";
						styleBoldEnabled = false;
					}
					else if(tokenValue == 1) {
						styleBoldEnabled = true;
					}
					else if(tokenValue == 30) {
						styleFgColour = "black";
					}
					else if(tokenValue == 31) {
						styleFgColour = "red";
					}
					else if(tokenValue == 32) {
						styleFgColour = "green";
					}
					else if(tokenValue == 33) {
						styleFgColour = "yellow";
					}
					else if(tokenValue == 34) {
						styleFgColour = "blue";
					}
					else if(tokenValue == 35) {
						styleFgColour = "magenta";
					}
					else if(tokenValue == 36) {
						styleFgColour = "cyan";
					}
					else if(tokenValue == 37) {
						styleFgColour = "white";
					}
				}
				
				currentStyleName = styleFgColour + "-" + (styleBoldEnabled ? "bright" : "normal");
				
				prevFind = endPos + 1;
				findPos = endPos + 1;
			}
			else {
				break;
			}
		}
		
		if(prevFind < inputText.length()) {
			try {
				doc.insertString(doc.getLength(), inputText.substring(prevFind, inputText.length()), inputPane.getStyle(currentStyleName));
			} catch (BadLocationException e) { }
		}
		
		scrollInputToEnd();
	}
	
	public void setText(String text) {
		outputPane.setText(text);
	}
	
	public void setConnected(boolean connected) {
		controlsPanel.setConnected(connected);
	}
	
	@Override
	public void componentHidden(ComponentEvent e) {
		processSize();
	}

	@Override
	public void componentMoved(ComponentEvent e) {
		processSize();
	}

	@Override
	public void componentResized(ComponentEvent e) {
		processSize();
	}

	@Override
	public void componentShown(ComponentEvent e) {
		processSize();
	}
}
